//+------------------------------------------------------------------+
//|                                                      fileapi.mqh |
//|                             Copyright 2000-2025, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#include <WinAPI/windef.h>

// 流信息级别枚举
enum STREAM_INFO_LEVELS
{
    FindStreamInfoStandard,        // 标准流信息
    FindStreamInfoMaxInfoLevel     // 最大流信息级别
};

// 文件信息结构
struct BY_HANDLE_FILE_INFORMATION
{
    uint dwFileAttributes;         // 文件属性
    FILETIME ftCreationTime;       // 创建时间
    FILETIME ftLastAccessTime;     // 最后访问时间
    FILETIME ftLastWriteTime;      // 最后写入时间
    uint dwVolumeSerialNumber;     // 卷序列号
    uint nFileSizeHigh;            // 文件大小高32位
    uint nFileSizeLow;             // 文件大小低32位
    uint nNumberOfLinks;           // 链接数
    uint nFileIndexHigh;           // 文件索引高32位
    uint nFileIndexLow;            // 文件索引低32位
};

// 创建文件扩展参数
struct CREATEFILE2_EXTENDED_PARAMETERS
{
    uint dwSize;                   // 结构大小
    uint dwFileAttributes;         // 文件属性
    uint dwFileFlags;              // 文件标志
    uint dwSecurityQosFlags;       // 安全QoS标志
    PVOID lpSecurityAttributes;    // 安全属性指针
    HANDLE hTemplateFile;          // 模板文件句柄
};

// 文件属性数据
struct FILE_ATTRIBUTE_DATA
{
    uint dwFileAttributes;         // 文件属性
    FILETIME ftCreationTime;       // 创建时间
    FILETIME ftLastAccessTime;     // 最后访问时间
    FILETIME ftLastWriteTime;      // 最后写入时间
    uint nFileSizeHigh;            // 文件大小高32位
    uint nFileSizeLow;             // 文件大小低32位
};

// 查找流数据
struct FIND_STREAM_DATA
{
    long StreamSize;               // 流大小
    short cStreamName[MAX_PATH+36]; // 流名称
};

// 查找文件数据
struct FIND_DATAW
{
    uint dwFileAttributes;         // 文件属性
    FILETIME ftCreationTime;       // 创建时间
    FILETIME ftLastAccessTime;     // 最后访问时间
    FILETIME ftLastWriteTime;      // 最后写入时间
    uint nFileSizeHigh;            // 文件大小高32位
    uint nFileSizeLow;             // 文件大小低32位
    uint dwReserved0;              // 保留字段0
    uint dwReserved1;              // 保留字段1
    short cFileName[MAX_PATH];     // 文件名
    short cAlternateFileName[14];  // 短文件名
};

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
#import "kernel32.dll"
/// 检查文件API是否使用ANSI编码
int AreFileApisANSI(void);

/// 比较两个文件时间
/// @param file_time1 第一个文件时间
/// @param file_time2 第二个文件时间
/// @return 比较结果
int CompareFileTime(FILETIME &file_time1, FILETIME &file_time2);

/// 创建目录
/// @param path_name 目录路径
/// @param security_attributes 安全属性
/// @return 操作结果
int CreateDirectoryW(const string path_name, PVOID security_attributes);

/// 创建文件(扩展版本)
/// @param file_name 文件名
/// @param desired_access 访问权限
/// @param share_mode 共享模式
/// @param creation_disposition 创建方式
/// @param create_ex_params 扩展参数
/// @return 文件句柄
HANDLE CreateFile2(const string file_name, uint desired_access, uint share_mode, 
                  uint creation_disposition, CREATEFILE2_EXTENDED_PARAMETERS &create_ex_params);

/// 创建文件
/// @param file_name 文件名
/// @param desired_access 访问权限
/// @param share_mode 共享模式
/// @param security_attributes 安全属性
/// @param creation_disposition 创建方式
/// @param flags_and_attributes 标志和属性
/// @param template_file 模板文件句柄
/// @return 文件句柄
HANDLE CreateFileW(const string file_name, uint desired_access, uint share_mode, 
                  PVOID security_attributes, uint creation_disposition, 
                  uint flags_and_attributes, HANDLE template_file);

/// 定义DOS设备
/// @param flags 标志
/// @param device_name 设备名
/// @param target_path 目标路径
/// @return 操作结果
int DefineDosDeviceW(uint flags, const string device_name, const string target_path);

/// 删除文件
/// @param file_name 文件名
/// @return 操作结果
int DeleteFileW(const string file_name);

/// 删除卷挂载点
/// @param volume_mount_point 卷挂载点
/// @return 操作结果
int DeleteVolumeMountPointW(const string volume_mount_point);

/// 文件时间转换为本地文件时间
/// @param file_time 文件时间
/// @param local_file_time 本地文件时间
/// @return 操作结果
int FileTimeToLocalFileTime(FILETIME &file_time, FILETIME &local_file_time);

/// 关闭查找句柄
/// @param find_file 查找句柄
/// @return 操作结果
int FindClose(HANDLE find_file);

/// 关闭变更通知句柄
/// @param change_handle 变更通知句柄
/// @return 操作结果
int FindCloseChangeNotification(HANDLE change_handle);

/// 查找第一个变更通知
/// @param path_name 路径名
/// @param watch_subtree 是否监视子树
/// @param notify_filter 通知过滤器
/// @return 变更通知句柄
HANDLE FindFirstChangeNotificationW(const string path_name, int watch_subtree, uint notify_filter);

/// 查找第一个文件(扩展版本)
/// @param file_name 文件名
/// @param info_level_id 信息级别
/// @param find_file_data 文件数据
/// @param search_op 搜索操作
/// @param search_filter 搜索过滤器
/// @param additional_flags 附加标志
/// @return 查找句柄
HANDLE FindFirstFileExW(const string file_name, FINDEX_INFO_LEVELS info_level_id, 
                        FIND_DATAW &find_file_data, FINDEX_SEARCH_OPS search_op, 
                        PVOID search_filter, uint additional_flags);

/// 查找第一个文件名
/// @param file_name 文件名
/// @param flags 标志
/// @param StringLength 字符串长度
/// @param LinkName 链接名
/// @return 查找句柄
HANDLE FindFirstFileNameW(const string file_name, uint flags, uint &StringLength, ushort &LinkName[]);

/// 查找第一个文件
/// @param file_name 文件名
/// @param find_file_data 文件数据
/// @return 查找句柄
HANDLE FindFirstFileW(const string file_name, FIND_DATAW &find_file_data);

/// 查找第一个流
/// @param file_name 文件名
/// @param InfoLevel 信息级别
/// @param find_stream_data 流数据
/// @param flags 标志
/// @return 查找句柄
HANDLE FindFirstStreamW(const string file_name, STREAM_INFO_LEVELS InfoLevel, 
                        FIND_STREAM_DATA &find_stream_data, uint flags);

/// 查找第一个卷
/// @param volume_name 卷名
/// @param buffer_length 缓冲区长度
/// @return 查找句柄
HANDLE FindFirstVolumeW(ushort &volume_name[], uint &buffer_length);

/// 查找下一个变更通知
/// @param change_handle 变更通知句柄
/// @return 操作结果
int FindNextChangeNotification(HANDLE change_handle);

/// 查找下一个文件名
/// @param find_stream 查找句柄
/// @param StringLength 字符串长度
/// @param LinkName 链接名
/// @return 操作结果
int FindNextFileNameW(HANDLE find_stream, uint &StringLength, ushort &LinkName[]);

/// 查找下一个文件
/// @param find_file 查找句柄
/// @param find_file_data 文件数据
/// @return 操作结果
int FindNextFileW(HANDLE find_file, FIND_DATAW &find_file_data);

/// 查找下一个流
/// @param find_stream 查找句柄
/// @param find_stream_data 流数据
/// @return 操作结果
int FindNextStreamW(HANDLE find_stream, FIND_STREAM_DATA &find_stream_data);

/// 查找下一个卷
/// @param find_volume 查找句柄
/// @param volume_name 卷名
/// @param buffer_length 缓冲区长度
/// @return 操作结果
int FindNextVolumeW(HANDLE find_volume, ushort &volume_name[], uint &buffer_length);

/// 关闭卷查找句柄
/// @param find_volume 查找句柄
/// @return 操作结果
int FindVolumeClose(HANDLE find_volume);

/// 刷新文件缓冲区
/// @param file 文件句柄
/// @return 操作结果
int FlushFileBuffers(HANDLE file);

/// 获取压缩文件大小
/// @param file_name 文件名
/// @param file_size_high 文件大小高32位
/// @return 文件大小低32位
uint GetCompressedFileSizeW(const string file_name, uint &file_size_high);

/// 获取磁盘空闲空间(扩展版本)
/// @param directory_name 目录名
/// @param free_bytes_available_to_caller 可用空间
/// @param total_number_of_bytes 总空间
/// @param total_number_of_free_bytes 空闲空间
/// @return 操作结果
int GetDiskFreeSpaceExW(const string directory_name, ulong &free_bytes_available_to_caller, 
                        ulong &total_number_of_bytes, ulong &total_number_of_free_bytes);

/// 获取磁盘空闲空间
/// @param root_path_name 根路径名
/// @param sectors_per_cluster 每簇扇区数
/// @param bytes_per_sector 每扇区字节数
/// @param number_of_free_clusters 空闲簇数
/// @param total_number_of_clusters 总簇数
/// @return 操作结果
int GetDiskFreeSpaceW(const string root_path_name, uint &sectors_per_cluster, 
                     uint &bytes_per_sector, uint &number_of_free_clusters, 
                     uint &total_number_of_clusters);

/// 获取驱动器类型
/// @param root_path_name 根路径名
/// @return 驱动器类型
uint GetDriveTypeW(const string root_path_name);

/// 获取文件属性(扩展版本)
/// @param file_name 文件名
/// @param info_level_id 信息级别
/// @param file_information 文件信息
/// @return 操作结果
int GetFileAttributesExW(const string file_name, GET_FILEEX_INFO_LEVELS info_level_id, 
                         FILE_ATTRIBUTE_DATA &file_information);

/// 获取文件属性
/// @param file_name 文件名
/// @return 文件属性
uint GetFileAttributesW(const string file_name);

/// 通过句柄获取文件信息
/// @param file 文件句柄
/// @param file_information 文件信息
/// @return 操作结果
int GetFileInformationByHandle(HANDLE file, BY_HANDLE_FILE_INFORMATION &file_information);

/// 获取文件大小
/// @param file 文件句柄
/// @param file_size_high 文件大小高32位
/// @return 文件大小低32位
uint GetFileSize(HANDLE file, uint &file_size_high);

/// 获取文件大小(扩展版本)
/// @param file 文件句柄
/// @param file_size 文件大小
/// @return 操作结果
int GetFileSizeEx(HANDLE file, long &file_size);

/// 获取文件时间
/// @param file 文件句柄
/// @param creation_time 创建时间
/// @param last_access_time 最后访问时间
/// @param last_write_time 最后写入时间
/// @return 操作结果
int GetFileTime(HANDLE file, FILETIME &creation_time, FILETIME &last_access_time, FILETIME &last_write_time);

/// 获取文件类型
/// @param file 文件句柄
/// @return 文件类型
uint GetFileType(HANDLE file);

/// 通过句柄获取最终路径名
/// @param file 文件句柄
/// @param file_path 文件路径
/// @param file_path_len 文件路径长度
/// @param flags 标志
/// @return 路径长度
uint GetFinalPathNameByHandleW(HANDLE file, ushort &file_path[], uint file_path_len, uint flags);

/// 获取完整路径名
/// @param file_name 文件名
/// @param buffer_length 缓冲区长度
/// @param buffer 缓冲区
/// @param file_part 文件部分
/// @return 路径长度
uint GetFullPathNameW(const string file_name, uint buffer_length, ushort &buffer[], ushort &file_part[]);

/// 获取逻辑驱动器位掩码
/// @return 逻辑驱动器位掩码
uint GetLogicalDrives(void);

/// 获取逻辑驱动器字符串
/// @param buffer_length 缓冲区长度
/// @param buffer 缓冲区
/// @return 字符串长度
uint GetLogicalDriveStringsW(uint buffer_length, ushort &buffer[]);

/// 获取长路径名
/// @param short_path 短路径
/// @param long_path 长路径
/// @param buffer 缓冲区大小
/// @return 路径长度
uint GetLongPathNameW(const string short_path, string &long_path, uint buffer);

/// 获取短路径名
/// @param long_path 长路径
/// @param short_path 短路径
/// @param buffer 缓冲区大小
/// @return 路径长度
uint GetShortPathNameW(const string long_path, string &short_path, uint buffer);

/// 获取临时文件名
/// @param path_name 路径名
/// @param prefix_string 前缀字符串
/// @param unique 唯一标识
/// @param temp_file_name 临时文件名
/// @return 操作结果
uint GetTempFileNameW(const string path_name, const string prefix_string, uint unique, ushort &temp_file_name[]);

/// 获取临时路径
/// @param buffer_length 缓冲区长度
/// @param buffer 缓冲区
/// @return 路径长度
uint GetTempPathW(uint buffer_length, ushort &buffer[]);

/// 通过句柄获取卷信息
/// @param file 文件句柄
/// @param volume_name_buffer 卷名缓冲区
/// @param volume_name_size 卷名大小
/// @param volume_serial_number 卷序列号
/// @param maximum_component_length 最大组件长度
/// @param file_system_flags 文件系统标志
/// @param file_system_name_buffer 文件系统名缓冲区
/// @param file_system_name_size 文件系统名大小
/// @return 操作结果
int GetVolumeInformationByHandleW(HANDLE file, ushort &volume_name_buffer[], uint volume_name_size, 
                                  uint &volume_serial_number, uint &maximum_component_length, 
                                  uint &file_system_flags, ushort &file_system_name_buffer[], 
                                  uint file_system_name_size);

/// 获取卷信息
/// @param root_path_name 根路径名
/// @param volume_name_buffer 卷名缓冲区
/// @param volume_name_size 卷名大小
/// @param volume_serial_number 卷序列号
/// @param maximum_component_length 最大组件长度
/// @param file_system_flags 文件系统标志
/// @param file_system_name_buffer 文件系统名缓冲区
/// @param file_system_name_size 文件系统名大小
/// @return 操作结果
int GetVolumeInformationW(const string root_path_name, ushort &volume_name_buffer[], uint volume_name_size, 
                           uint &volume_serial_number, uint &maximum_component_length, 
                           uint &file_system_flags, ushort &file_system_name_buffer[], 
                           uint file_system_name_size);

/// 获取卷挂载点的卷名
/// @param volume_mount_point 卷挂载点
/// @param volume_name 卷名
/// @param buffer_length 缓冲区长度
/// @return 操作结果
int GetVolumeNameForVolumeMountPointW(const string volume_mount_point, string volume_name, uint buffer_length);

/// 获取卷名的路径名
/// @param volume_name 卷名
/// @param volume_path_names 卷路径名
/// @param buffer_length 缓冲区长度
/// @param return_length 返回长度
/// @return 操作结果
int GetVolumePathNamesForVolumeNameW(const string volume_name, string volume_path_names, uint buffer_length, uint &return_length);

/// 获取文件路径的卷路径
/// @param file_name 文件名
/// @param volume_path_name 卷路径名
/// @param buffer_length 缓冲区长度
/// @return 操作结果
int GetVolumePathNameW(const string file_name, ushort &volume_path_name[], uint buffer_length);

/// 本地文件时间转换为文件时间
/// @param local_file_time 本地文件时间
/// @param file_time 文件时间
/// @return 操作结果
int LocalFileTimeToFileTime(FILETIME &local_file_time, FILETIME &file_time);

/// 锁定文件区域
/// @param file 文件句柄
/// @param file_offset_low 文件偏移低32位
/// @param file_offset_high 文件偏移高32位
/// @param number_of_bytes_to_lock_low 锁定字节数低32位
/// @param number_of_bytes_to_lock_high 锁定字节数高32位
/// @return 操作结果
int LockFile(HANDLE file, uint file_offset_low, uint file_offset_high, 
             uint number_of_bytes_to_lock_low, uint number_of_bytes_to_lock_high);

/// 锁定文件区域(扩展版本)
/// @param file 文件句柄
/// @param flags 标志
/// @param reserved 保留字段
/// @param number_of_bytes_to_lock_low 锁定字节数低32位
/// @param number_of_bytes_to_lock_high 锁定字节数高32位
/// @param overlapped 重叠结构
/// @return 操作结果
int LockFileEx(HANDLE file, uint flags, uint reserved, uint number_of_bytes_to_lock_low, 
               uint number_of_bytes_to_lock_high, OVERLAPPED &overlapped);

/// 查询DOS设备
/// @param device_name 设备名
/// @param target_path 目标路径
/// @param max 最大长度
/// @return 路径长度
uint QueryDosDeviceW(const string device_name, ushort &target_path[], uint max);

/// 读取文件
/// @param file 文件句柄
/// @param buffer 缓冲区
/// @param number_of_bytes_to_read 要读取的字节数
/// @param number_of_bytes_read 已读取字节数
/// @param overlapped 重叠结构
/// @return 操作结果
int ReadFile(HANDLE file, ushort &buffer[], uint number_of_bytes_to_read, 
             uint &number_of_bytes_read, OVERLAPPED &overlapped);

/// 读取文件(无重叠结构)
/// @param file 文件句柄
/// @param buffer 缓冲区
/// @param number_of_bytes_to_read 要读取的字节数
/// @param number_of_bytes_read 已读取字节数
/// @param overlapped 重叠结构指针
/// @return 操作结果
int ReadFile(HANDLE file, ushort &buffer[], uint number_of_bytes_to_read, 
             uint &number_of_bytes_read, PVOID overlapped);

/// 分散读取文件
/// @param file 文件句柄
/// @param segment_array 段数组
/// @param number_of_bytes_to_read 要读取的字节数
/// @param reserved 保留字段
/// @param overlapped 重叠结构
/// @return 操作结果
int ReadFileScatter(HANDLE file, FILE_SEGMENT_ELEMENT &segment_array[], uint number_of_bytes_to_read, 
                    uint &reserved, OVERLAPPED &overlapped);

/// 分散读取文件(无重叠结构)
/// @param file 文件句柄
/// @param segment_array 段数组
/// @param number_of_bytes_to_read 要读取的字节数
/// @param reserved 保留字段
/// @param overlapped 重叠结构指针
/// @return 操作结果
int ReadFileScatter(HANDLE file, FILE_SEGMENT_ELEMENT &segment_array[], uint number_of_bytes_to_read, 
                    uint &reserved, PVOID overlapped);

/// 删除目录
/// @param path_name 路径名
/// @return 操作结果
int RemoveDirectoryW(const string path_name);

/// 设置文件结束位置
/// @param file 文件句柄
/// @return 操作结果
int SetEndOfFile(HANDLE file);

/// 设置文件API使用ANSI编码
void SetFileApisToANSI(void);

/// 设置文件API使用OEM编码
void SetFileApisToOEM(void);

/// 设置文件属性
/// @param file_name 文件名
/// @param file_attributes 文件属性
/// @return 操作结果
int SetFileAttributesW(const string file_name, uint file_attributes);

/// 通过句柄设置文件信息
/// @param file 文件句柄
/// @param FileInformationClass 文件信息类
/// @param file_information 文件信息
/// @param buffer_size 缓冲区大小
/// @return 操作结果
int SetFileInformationByHandle(HANDLE file, FILE_INFO_BY_HANDLE_CLASS FileInformationClass, 
                              FILE_INFO &file_information, uint buffer_size);

/// 设置文件I/O重叠范围
/// @param FileHandle 文件句柄
/// @param OverlappedRangeStart 重叠范围起始
/// @param Length 长度
/// @return 操作结果
int SetFileIoOverlappedRange(HANDLE FileHandle, uchar &OverlappedRangeStart, uint Length);

/// 设置文件指针
/// @param file 文件句柄
/// @param distance_to_move 移动距离
/// @param distance_to_move_high 移动距离高32位
/// @param move_method 移动方法
/// @return 新指针位置
uint SetFilePointer(HANDLE file, long distance_to_move, long &distance_to_move_high, uint move_method);

/// 设置文件指针(扩展版本)
/// @param file 文件句柄
/// @param distance_to_move 移动距离
/// @param new_file_pointer 新文件指针
/// @param move_method 移动方法
/// @return 操作结果
int SetFilePointerEx(HANDLE file, long distance_to_move, long &new_file_pointer, uint move_method);

/// 设置文件时间
/// @param file 文件句柄
/// @param creation_time 创建时间
/// @param last_access_time 最后访问时间
/// @param last_write_time 最后写入时间
/// @return 操作结果
int SetFileTime(HANDLE file, FILETIME &creation_time, FILETIME &last_access_time, FILETIME &last_write_time);

/// 设置文件有效数据
/// @param file 文件句柄
/// @param ValidDataLength 有效数据长度
/// @return 操作结果
int SetFileValidData(HANDLE file, long ValidDataLength);

/// 解锁文件区域
/// @param file 文件句柄
/// @param file_offset_low 文件偏移低32位
/// @param file_offset_high 文件偏移高32位
/// @param number_of_bytes_to_unlock_low 解锁字节数低32位
/// @param number_of_bytes_to_unlock_high 解锁字节数高32位
/// @return 操作结果
int UnlockFile(HANDLE file, uint file_offset_low, uint file_offset_high, 
               uint number_of_bytes_to_unlock_low, uint number_of_bytes_to_unlock_high);

/// 解锁文件区域(扩展版本)
/// @param file 文件句柄
/// @param reserved 保留字段
/// @param number_of_bytes_to_unlock_low 解锁字节数低32位
/// @param number_of_bytes_to_unlock_high 解锁字节数高32位
/// @param overlapped 重叠结构
/// @return 操作结果
int UnlockFileEx(HANDLE file, uint reserved, uint number_of_bytes_to_unlock_low, 
                 uint number_of_bytes_to_unlock_high, OVERLAPPED &overlapped);

/// 写入文件
/// @param file 文件句柄
/// @param buffer 缓冲区
/// @param number_of_bytes_to_write 要写入的字节数
/// @param number_of_bytes_written 已写入字节数
/// @param overlapped 重叠结构
/// @return 操作结果
int WriteFile(HANDLE file, const ushort &buffer[], uint number_of_bytes_to_write, 
              uint &number_of_bytes_written, OVERLAPPED &overlapped);

/// 写入文件(无重叠结构)
/// @param file 文件句柄
/// @param buffer 缓冲区
/// @param number_of_bytes_to_write 要写入的字节数
/// @param number_of_bytes_written 已写入字节数
/// @param overlapped 重叠结构指针
/// @return 操作结果
int WriteFile(HANDLE file, const ushort &buffer[], uint number_of_bytes_to_write, 
              uint &number_of_bytes_written, PVOID overlapped);

/// 聚集写入文件
/// @param file 文件句柄
/// @param segment_array 段数组
/// @param number_of_bytes_to_write 要写入的字节数
/// @param reserved 保留字段
/// @param overlapped 重叠结构
/// @return 操作结果
int WriteFileGather(HANDLE file, FILE_SEGMENT_ELEMENT &segment_array[], uint number_of_bytes_to_write, 
                    uint &reserved, OVERLAPPED &overlapped);

/// 聚集写入文件(无重叠结构)
/// @param file 文件句柄
/// @param segment_array 段数组
/// @param number_of_bytes_to_write 要写入的字节数
/// @param reserved 保留字段
/// @param overlapped 重叠结构指针
/// @return 操作结果
int WriteFileGather(HANDLE file, FILE_SEGMENT_ELEMENT &segment_array[], uint number_of_bytes_to_write, 
                    uint &reserved, PVOID overlapped);
#import
//+------------------------------------------------------------------+